﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Windows.Forms;
using PayexpDAL;
using Utilities;
using System.Globalization;
using ExcelHandler;
using PresentationControls;
using PayexpUserControls;

namespace Moneymatters
{
    // this contains code related to the first tab
    // where we add and edit transactions
    // some part may be present in the CommonFunctionality.cs
    public partial class MainForm
    {
        #region Private Fields

        private Dictionary<Guid, PanelDetails> mainPanelMap = new Dictionary<Guid, PanelDetails>();
        private Dictionary<Guid, PanelDetails> chequeDetailsPanelMap = new Dictionary<Guid, PanelDetails>();
        private Panel currentGrayPanel;

        #endregion Private Fields

        #region Properties
        #endregion Properties

        #region Private Methods

        /// <summary>
        /// Highlights the main  trans row with gray and sets the currentGrayPanel object 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void transEntryMainPanel_Click(object sender, EventArgs e)
        {
            if (currentGrayPanel != null)
            {
                currentGrayPanel.BackColor = Color.Empty;
            }

            currentGrayPanel = (Panel)sender;
            currentGrayPanel.BackColor = Color.LightGray;

            ClearChequeDetailsPanel();

            PanelDetails mainTransRowPanelDetails = null;
            Guid mainTrasnEntryPanelGuid = (Guid)currentGrayPanel.Tag;
            if (mainPanelMap.ContainsKey(mainTrasnEntryPanelGuid))
            {
                mainTransRowPanelDetails = mainPanelMap[mainTrasnEntryPanelGuid];

                this.panelForChequeDetailsScroll.SuspendLayout();
                foreach (PanelDetails chequeDetails in mainTransRowPanelDetails.ChildrenChequeDetails)
                {
                    this.panelForChequeDetailsScroll.Controls.Add(chequeDetails.PanelWithControls);
                }

                this.panelForChequeDetailsScroll.ResumeLayout(false);
            }
        }

        private void ClearMainTransactionEntryScrollPanel()
        {
            this.panelForScrollMain.Controls.Clear();
        }

        private void ClearChequeDetailsPanel()
        {
            this.panelForChequeDetailsScroll.Controls.Clear();
        }

        private void EnableDisableControlsInPanel(Panel panel, bool value)
        {
            for (int i = 0; i < panel.Controls.Count - 1; i++)
            {
                panel.Controls[i].Enabled = value;
            }
        }

        private string DeleteAndUndo(Dictionary<Guid, PanelDetails> panelMapToUse, Guid panelGuid)
        {
            string buttonText = string.Empty;
            if (panelMapToUse.ContainsKey(panelGuid))
            {
                PanelDetails panelDetails = panelMapToUse[panelGuid];
                bool enabled = false;

                if (panelDetails.IsDeleted && !panelDetails.IsParentDeleted)
                {
                    enabled = true;
                    buttonText = "Delete";
                    panelDetails.IsDeleted = false;
                }
                else
                {
                    enabled = false;
                    buttonText = "Undo Delete";
                    panelDetails.IsDeleted = true;
                }

                Panel containingPanel = panelMapToUse[panelGuid].PanelWithControls;
                EnableDisableControlsInPanel(containingPanel, enabled);
            }

            return buttonText;
        }

        private void mainRowDeleteButton_Click(object sender, EventArgs e)
        {
            Button button = (Button)sender;
            Guid panelGuid = (Guid)button.Tag;

            PanelDetails panelDetails = mainPanelMap[panelGuid];
            if (panelDetails.IsNew)
            {
                RedrawPanel(panelForScrollMain, new List<Panel>() { panelDetails.PanelWithControls });
                List<Panel> chequeDetailsPanelsToRemove = new List<Panel>();
                panelDetails.ChildrenChequeDetails.ForEach(t => chequeDetailsPanelsToRemove.Add(t.PanelWithControls));
                RedrawPanel(panelForChequeDetailsScroll, chequeDetailsPanelsToRemove);

                panelDetails.ChildrenChequeDetails.ForEach(t => chequeDetailsPanelMap.Remove(t.Guid));
                mainPanelMap.Remove(panelDetails.Guid);

                return;
            }

            string buttonTextToSetAfterOperation = DeleteAndUndo(mainPanelMap, panelGuid);
            if (!string.IsNullOrEmpty(buttonTextToSetAfterOperation))
            {
                button.Text = buttonTextToSetAfterOperation;
            }


            foreach (PanelDetails chequeDetails in panelDetails.ChildrenChequeDetails/*.Where(t => !t.IsDeleted)*/)
            {
                chequeDetails.IsParentDeleted = panelDetails.IsDeleted;
                string buttonTextchequeDetails = DeleteAndUndo(chequeDetailsPanelMap, (Guid)chequeDetails.PanelWithControls.Tag);
                if (!chequeDetails.IsNew && !string.IsNullOrEmpty(buttonTextchequeDetails))
                {
                    Button chequeButton =
                        (Button)chequeDetails.PanelWithControls.Controls[chequeDetails.PanelWithControls.Controls.Count - 1];
                    chequeButton.Text = buttonTextchequeDetails;
                }
            }
        }

        private void chequeDetailsRowDeleteButton_Click(object sender, EventArgs e)
        {
            Button button = (Button)sender;
            Guid panelGuid = (Guid)button.Tag;

            PanelDetails panelDetails = chequeDetailsPanelMap[panelGuid];
            if (panelDetails.IsNew)
            {
                RedrawPanel(panelForChequeDetailsScroll, new List<Panel>() { panelDetails.PanelWithControls });
                panelDetails.IsDiscarded = true;
                chequeDetailsPanelMap.Remove(panelGuid);

                foreach (PanelDetails mainPanelDetails in mainPanelMap.Values)
                {
                    mainPanelDetails.ChildrenChequeDetails.RemoveAll(t => t.IsDiscarded);
                }

                return;
            }

            string buttonTextToSetAfterOperation = DeleteAndUndo(chequeDetailsPanelMap, panelGuid);
            if (!string.IsNullOrEmpty(buttonTextToSetAfterOperation))
            {
                button.Text = buttonTextToSetAfterOperation;
            }
        }

        /// <summary>
        /// MAIN ROW
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonAddRowMain_Click(object sender, EventArgs e)
        {
            if (this.panelForScrollMain.Controls.Count >= 10)
            {
                MessageBox.Show("You can enter a maximum of 10 transactions at a time.", "Maximum number of transactions", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            ClearChequeDetailsPanel();
            CreateMainTransRowFromData(null);

            if (currentGrayPanel != null)
            {
                Guid mainPanelGuid = (Guid)currentGrayPanel.Tag;
                CreateChequeDetailsRowFromData(mainPanelGuid, null);
            }
        }

        // NOT USED
        private void AddChequeRow(string selectedTransactionMode)
        {
            if (currentGrayPanel != null)
            {
                PanelDetails mainTransRowPanelDetails = null;
                if (mainPanelMap.ContainsKey((Guid)currentGrayPanel.Tag))
                {
                    mainTransRowPanelDetails = mainPanelMap[(Guid)currentGrayPanel.Tag];
                    if (mainTransRowPanelDetails.IsDeleted)
                    {
                        return;
                    }
                    else if (mainTransRowPanelDetails.ChildrenChequeDetails.Count >= 3)
                    {
                        MessageBox.Show("You can enter a maximum of 3 cheque details per transactions.", "Maximum number of cheque details", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                }
            }
        }

        // NOT USED SINCE THE BUTTON IS KEPT HIDDEN
        private void buttonAddDetailsRow_Click(object sender, EventArgs e)
        {
            if (currentGrayPanel != null)
            {
                ComboBox transactionMode = (ComboBox)currentGrayPanel.Controls[2];
                ComboBoxItem comboBoxItem = (ComboBoxItem)transactionMode.SelectedItem;
                StaticList staticList = (StaticList)comboBoxItem.Value;

                PanelDetails mainTransRowPanelDetails = null;
                if (mainPanelMap.ContainsKey((Guid)currentGrayPanel.Tag))
                {
                    mainTransRowPanelDetails = mainPanelMap[(Guid)currentGrayPanel.Tag];
                    if (mainTransRowPanelDetails.IsDeleted)
                    {
                        return;
                    }
                    else if (mainTransRowPanelDetails.ChildrenChequeDetails.Count >= 3)
                    {
                        MessageBox.Show("You can enter a maximum of 3 cheque details per transactions.", "Maximum number of cheque details", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                }

                CreateChequeDetailsRowFromData((Guid)currentGrayPanel.Tag, null);
            }
        }

        private void AddExistingOrClonedTransactionsMasterToMainDataEntryPanel(TransactionMaster existingOrClonedDataTransactionMaster,
                                                                               bool isNew)
        {
            if (!isNew)
            {
                foreach (PanelDetails existingPanelDetails in mainPanelMap.Values)
                {
                    if (existingPanelDetails.IsNew)
                    {
                        continue;
                    }

                    if (existingPanelDetails.DataForPersistence != null)
                    {
                        TransactionMaster existingTransactionMaster = (TransactionMaster)existingPanelDetails.DataForPersistence;
                        if (existingTransactionMaster.Id.Equals(existingOrClonedDataTransactionMaster.Id))
                        {
                            MessageBox.Show("Selected transaction is already present in the 'Add Or Edit' tab.", "Already present", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return;
                        }
                    }
                }
            }

            PanelDetails panelDetails = new PanelDetails(Guid.NewGuid(), isNew);
            panelDetails.DataForPersistence = existingOrClonedDataTransactionMaster;

            panelDetails.SelectedTransactionTypes.AddRange(GetTransactionType(existingOrClonedDataTransactionMaster.HeadDetailsHierarchyIdList));

            CreateMainTransRowFromData(panelDetails);

            foreach (TransactionMasterChequeDetail transactionMasterChequeDetail in existingOrClonedDataTransactionMaster.TransactionMasterChequeDetails.Where(t => t.IsActive))
            {
                PanelDetails panelDetailsChequeDetails = new PanelDetails(Guid.NewGuid(), false);
                panelDetailsChequeDetails.DataForPersistence = transactionMasterChequeDetail;
                CreateChequeDetailsRowFromData((Guid)currentGrayPanel.Tag,
                                                            panelDetailsChequeDetails);
            }
        }

        private void buttonClone_Click(object sender, EventArgs e)
        {
            if (this.panelForScrollMain.Controls.Count >= 10)
            {
                MessageBox.Show("You can enter a maximum of 10 transactions at a time.", "Maximum number of transactions", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (currentGrayPanel != null)
            {
                Guid mainPanelGuid = (Guid)currentGrayPanel.Tag;
                if (mainPanelMap.ContainsKey(mainPanelGuid))
                {
                    PanelDetails requiredPanelDetails = mainPanelMap[mainPanelGuid];

                    if (requiredPanelDetails.DataForPersistence != null)
                    {
                        TransactionMaster transactionMasterToClone = (TransactionMaster)requiredPanelDetails.DataForPersistence;
                        TransactionMaster clone = transactionMasterToClone.Clone();
                        AddExistingOrClonedTransactionsMasterToMainDataEntryPanel(clone, true);
                    }
                }
                else
                {
                    MessageBox.Show("Sorry, there was an error trying to clone the selected transaction.", "Error cloning", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            else
            {
                MessageBox.Show("Please select a row to clone.", "Row not selected", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

        }

        private void CreateMainTransRowFromData(PanelDetails panelDetails)
        {

            Panel lastPanelInScrollPanel = null;
            int offset;
            int offsetForReconcileCheckBox = 0;
            if (this.panelForScrollMain.Controls.Count > 0)
            {
                lastPanelInScrollPanel = (Panel)this.panelForScrollMain.Controls[this.panelForScrollMain.Controls.Count - 1];
                offset = 37;
            }
            else
            {
                lastPanelInScrollPanel = this.panelMainHeader;
                offset = -15;
                offsetForReconcileCheckBox = 6;
            }

            int x1 = lastPanelInScrollPanel.Controls[0].Location.X;
            int y1 = lastPanelInScrollPanel.Controls[0].Location.Y;
            int w1 = lastPanelInScrollPanel.Controls[0].Width;
            int h1 = lastPanelInScrollPanel.Controls[0].Height;

            int x2 = lastPanelInScrollPanel.Controls[1].Location.X;
            int y2 = lastPanelInScrollPanel.Controls[1].Location.Y;
            int w2 = lastPanelInScrollPanel.Controls[1].Width;
            int h2 = lastPanelInScrollPanel.Controls[1].Height;

            int x3 = lastPanelInScrollPanel.Controls[2].Location.X;
            int y3 = lastPanelInScrollPanel.Controls[2].Location.Y;
            int w3 = lastPanelInScrollPanel.Controls[2].Width;
            int h3 = lastPanelInScrollPanel.Controls[2].Height;

            int x4 = lastPanelInScrollPanel.Controls[3].Location.X;
            int y4 = lastPanelInScrollPanel.Controls[3].Location.Y;
            int w4 = lastPanelInScrollPanel.Controls[3].Width;
            int h4 = lastPanelInScrollPanel.Controls[3].Height;

            int x5 = lastPanelInScrollPanel.Controls[4].Location.X;
            int y5 = lastPanelInScrollPanel.Controls[4].Location.Y;
            int w5 = lastPanelInScrollPanel.Controls[4].Width;
            int h5 = lastPanelInScrollPanel.Controls[4].Height;

            int x6 = lastPanelInScrollPanel.Controls[5].Location.X;
            int y6 = lastPanelInScrollPanel.Controls[5].Location.Y;
            int w6 = lastPanelInScrollPanel.Controls[5].Width;
            int h6 = lastPanelInScrollPanel.Controls[5].Height;

            int x7 = lastPanelInScrollPanel.Controls[6].Location.X;
            int y7 = lastPanelInScrollPanel.Controls[6].Location.Y;
            int w7 = lastPanelInScrollPanel.Controls[6].Width;
            int h7 = lastPanelInScrollPanel.Controls[6].Height;

            int x8 = lastPanelInScrollPanel.Controls[7].Location.X;
            int y8 = lastPanelInScrollPanel.Controls[7].Location.Y;
            int w8 = lastPanelInScrollPanel.Controls[7].Width;
            int h8 = lastPanelInScrollPanel.Controls[7].Height;

            int x9 = lastPanelInScrollPanel.Controls[8].Location.X;
            int y9 = lastPanelInScrollPanel.Controls[8].Location.Y;
            int w9 = lastPanelInScrollPanel.Controls[8].Width;
            int h9 = lastPanelInScrollPanel.Controls[8].Height;

            int x10 = lastPanelInScrollPanel.Controls[9].Location.X + offsetForReconcileCheckBox; // for the check box
            int y10 = lastPanelInScrollPanel.Controls[9].Location.Y;
            int w10 = lastPanelInScrollPanel.Controls[9].Width;
            int h10 = lastPanelInScrollPanel.Controls[9].Height;


            //int panelX = lastPanelInScrollPanel.Location.X;
            int panelX = 0;
            int panelY = lastPanelInScrollPanel.Location.Y;
            int panelW = lastPanelInScrollPanel.Width;
            int panelH = lastPanelInScrollPanel.Height;

            if (panelDetails == null)
            {
                panelDetails = new PanelDetails(Guid.NewGuid(), true);
            }

            CreatePanelTransactionEntryRow(x1, y1, w1, h1,
                                                            x2, y2, w2, h2,
                                                            x3, y3, w3, h3,
                                                            x4, y4, w4, h4,
                                                            x5, y5, w5, h5,
                                                            x6, y6, w6, h6,
                                                            x7, y7, w7, h7,
                                                            x8, y8, w8, h8,
                                                            x9, y9, w9, h9,
                                                            x10, y10, w10, h10,
                                                            panelX, panelY, panelW, panelH, offset,
                                                            panelDetails);



            //Guid guid = Guid.NewGuid();
            //newDataPanel.Name = guid.ToString();
            //newDataPanel.Tag = guid;
            //foreach (Control control in newDataPanel.Controls)
            //{
            //    control.Tag = guid;
            //}
            if (!mainPanelMap.ContainsKey(panelDetails.Guid))
            {
                mainPanelMap.Add(panelDetails.Guid, panelDetails);
            }

            panelDetails.PanelWithControls.MouseClick += transEntryMainPanel_Click;
            //newDataPanel.MouseDoubleClick += transEntryMainPanel_DoubleClick;



            panelDetails.PanelWithControls.SuspendLayout();
            this.panelForScrollMain.SuspendLayout();
            this.groupBoxMain.SuspendLayout();
            this.tabPageMain.SuspendLayout();
            this.tabControl.SuspendLayout();
            this.SuspendLayout();

            this.panelForScrollMain.Controls.Add(panelDetails.PanelWithControls);

            this.tabControl.ResumeLayout(false);
            this.tabPageMain.ResumeLayout(false);
            this.groupBoxMain.ResumeLayout(false);
            this.panelForScrollMain.ResumeLayout(false);

            this.panelForScrollMain.VerticalScroll.Visible = true;


            panelDetails.PanelWithControls.ResumeLayout(false);
            this.ResumeLayout(false);
            this.panelForScrollMain.Refresh();

            if (currentGrayPanel != null)
            {
                currentGrayPanel.BackColor = Color.Empty;
            }

            currentGrayPanel = panelDetails.PanelWithControls;
            currentGrayPanel.BackColor = Color.LightGray;
        }

        /// <summary>
        /// DETAILS ROW for both TRANSACTION and CHEQUE
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CreateChequeDetailsRowFromData(Guid mainTrasnEntryPanelGuid, PanelDetails panelDetails)
        {
            PanelDetails mainTransRowPanelDetails = null;
            if (mainPanelMap.ContainsKey(mainTrasnEntryPanelGuid))
            {
                mainTransRowPanelDetails = mainPanelMap[mainTrasnEntryPanelGuid];
                if (mainTransRowPanelDetails.IsDeleted)
                {
                    return;
                }
            }


            if (mainTransRowPanelDetails != null)
            {
                // clear the panel except the header panel
                ClearChequeDetailsPanel();
                // add already existing rows
                foreach (PanelDetails chequeDetails in mainTransRowPanelDetails.ChildrenChequeDetails)
                {
                    this.panelForChequeDetailsScroll.Controls.Add(chequeDetails.PanelWithControls);
                }
            }

            // step three: add a new row
            Panel lastPanelInScrollPanel = null;
            int offset;
            if (this.panelForChequeDetailsScroll.Controls.Count > 0)
            {
                lastPanelInScrollPanel = (Panel)this.panelForChequeDetailsScroll.Controls[this.panelForChequeDetailsScroll.Controls.Count - 1];
                offset = 37;
            }
            else
            {
                lastPanelInScrollPanel = this.panelChequeDetailsHeader;
                offset = 1;
            }

            //Panel lastPanelInScrollPanel = (Panel)this.panelForChequeDetailsScroll.Controls[this.panelForChequeDetailsScroll.Controls.Count - 1];

            int x1 = lastPanelInScrollPanel.Controls[0].Location.X;
            int y1 = lastPanelInScrollPanel.Controls[0].Location.Y;
            int w1 = lastPanelInScrollPanel.Controls[0].Width;
            int h1 = lastPanelInScrollPanel.Controls[0].Height;

            int x2 = lastPanelInScrollPanel.Controls[1].Location.X;
            int y2 = lastPanelInScrollPanel.Controls[1].Location.Y;
            int w2 = lastPanelInScrollPanel.Controls[1].Width;
            int h2 = lastPanelInScrollPanel.Controls[0].Height;

            int x3 = lastPanelInScrollPanel.Controls[2].Location.X;
            int y3 = lastPanelInScrollPanel.Controls[2].Location.Y;
            int w3 = lastPanelInScrollPanel.Controls[2].Width;
            int h3 = lastPanelInScrollPanel.Controls[2].Height;

            int x4 = lastPanelInScrollPanel.Controls[3].Location.X;
            int y4 = lastPanelInScrollPanel.Controls[3].Location.Y;
            int w4 = lastPanelInScrollPanel.Controls[3].Width;
            int h4 = lastPanelInScrollPanel.Controls[3].Height;

            int x5 = lastPanelInScrollPanel.Controls[4].Location.X;
            int y5 = lastPanelInScrollPanel.Controls[4].Location.Y;
            int w5 = lastPanelInScrollPanel.Controls[4].Width;
            int h5 = lastPanelInScrollPanel.Controls[4].Height;

            int x6 = lastPanelInScrollPanel.Controls[5].Location.X;
            int y6 = lastPanelInScrollPanel.Controls[5].Location.Y;
            int w6 = lastPanelInScrollPanel.Controls[5].Width;
            int h6 = lastPanelInScrollPanel.Controls[5].Height;

            int x7 = lastPanelInScrollPanel.Controls[6].Location.X;
            int y7 = lastPanelInScrollPanel.Controls[6].Location.Y;
            int w7 = lastPanelInScrollPanel.Controls[6].Width;
            int h7 = lastPanelInScrollPanel.Controls[6].Height;


            //int panelX = lastPanelInScrollPanel.Location.X;
            int panelX = 0;
            int panelY = lastPanelInScrollPanel.Location.Y;
            int panelW = lastPanelInScrollPanel.Width;
            int panelH = lastPanelInScrollPanel.Height;

            if (panelDetails == null)
            {
                panelDetails = new PanelDetails(Guid.NewGuid(), true);

            }

            panelDetails.ParentTransactionMasterPanelDetails = mainTransRowPanelDetails;
            CreatePanelChequeDetailsRow(x1, y1, w1, h1,
                                                        x2, y2, w2, h2,
                                                        x3, y3, w3, h3,
                                                        x4, y4, w4, h4,
                                                        x5, y5, w5, h5,
                                                        x6, y6, w6, h6,
                                                        x7, y7, w7, h7,
                                                        panelX, panelY, panelW, panelH, offset,
                                                        panelDetails);

            //Guid guid = Guid.NewGuid();
            //newDataPanel.Name = guid.ToString();
            //newDataPanel.Tag = guid;
            //foreach (Control control in newDataPanel.Controls)
            //{
            //    control.Tag = guid;
            //}
            if (!chequeDetailsPanelMap.ContainsKey(panelDetails.Guid))
            {
                mainTransRowPanelDetails.ChildrenChequeDetails.Add(panelDetails);
                chequeDetailsPanelMap.Add(panelDetails.Guid, panelDetails);
            }

            panelDetails.PanelWithControls.SuspendLayout();
            this.panelForChequeDetailsScroll.SuspendLayout();
            this.tabPageChequeDetails.SuspendLayout();
            this.tabControlDetails.SuspendLayout();
            this.groupBoxChequeDetails.SuspendLayout();
            this.SuspendLayout();

            this.panelForChequeDetailsScroll.Controls.Add(panelDetails.PanelWithControls);

            this.groupBoxChequeDetails.ResumeLayout(false);
            this.tabControlDetails.ResumeLayout(false);
            this.tabPageChequeDetails.ResumeLayout(false);
            this.panelForChequeDetailsScroll.ResumeLayout(false);
            panelDetails.PanelWithControls.ResumeLayout(false);
            this.ResumeLayout(false);


            SetChequeRowDetailsPerParentHeadAndMode(mainTransRowPanelDetails);

            // SET THE ISDIRTY EVENT HANDLER NOW
            TextBox chequeNumber = (TextBox)panelDetails.PanelWithControls.Controls[0];
            chequeNumber.TextChanged += IsDirtyMarkerChequeDetailsRow;
            DateTimePicker chequeDate = (DateTimePicker)panelDetails.PanelWithControls.Controls[1];
            chequeDate.ValueChanged += IsDirtyMarkerChequeDetailsRow;
            ComboBox chequeStatus = (ComboBox)panelDetails.PanelWithControls.Controls[2];
            chequeStatus.SelectedIndexChanged += IsDirtyMarkerChequeDetailsRow;
            TextBox chequeAmount = (TextBox)panelDetails.PanelWithControls.Controls[3];
            chequeAmount.TextChanged += IsDirtyMarkerChequeDetailsRow;
            ComboBox drawnOnBank = (ComboBox)panelDetails.PanelWithControls.Controls[4];
            drawnOnBank.SelectedIndexChanged += IsDirtyMarkerChequeDetailsRow;
            TextBox narration = (TextBox)panelDetails.PanelWithControls.Controls[5];
            narration.TextChanged += IsDirtyMarkerChequeDetailsRow;
        }

        private void RedrawPanel(Panel panelToRedraw, List<Panel> panelsToRemove)
        {
            panelsToRemove.ForEach(t => panelToRedraw.Controls.Remove(t));

            Panel[] existingPanels = new Panel[panelToRedraw.Controls.Count];
            panelToRedraw.Controls.CopyTo(existingPanels, 0);

            panelToRedraw.Controls.Clear();

            panelToRedraw.SuspendLayout();

            int y = 0;
            foreach (Panel panel in existingPanels)
            {
                panel.SuspendLayout();
                panel.Location = new Point(panel.Location.X, y);
                panelToRedraw.Controls.Add(panel);

                y += 37;
            }

            foreach (Control panel in panelToRedraw.Controls)
            {
                panel.ResumeLayout(false);
            }

            panelToRedraw.ResumeLayout(false);
        }

        /// <summary>
        /// This creates the main trans entry row
        /// </summary>
        private void CreatePanelTransactionEntryRow(int x1, int y1, int w1, int h1,
                                                int x2, int y2, int w2, int h2,
                                                int x3, int y3, int w3, int h3,
                                                int x4, int y4, int w4, int h4,
                                                int x5, int y5, int w5, int h5,
                                                int x6, int y6, int w6, int h6,
                                                int x7, int y7, int w7, int h7,
                                                int x8, int y8, int w8, int h8,
                                                int x9, int y9, int w9, int h9,
                                                int x10, int y10, int w10, int h10,
                                                int panelX, int panelY, int panelW, int panelH, int offset,
                                                PanelDetails panelDetails)
        {

            panelDetails.PanelWithControls = new Panel();
            panelDetails.PanelWithControls.Height = panelH;
            panelDetails.PanelWithControls.Width = panelW;
            panelDetails.PanelWithControls.Location = new Point(panelX, (panelY + offset));
            panelDetails.PanelWithControls.Visible = true;
            panelDetails.PanelWithControls.Anchor = AnchorStyles.Top | AnchorStyles.Left;
            panelDetails.PanelWithControls.BorderStyle = BorderStyle.FixedSingle;

            panelDetails.PanelWithControls.Name = panelDetails.Guid.ToString();
            panelDetails.PanelWithControls.Tag = panelDetails.Guid;


            DateTimePicker transactionDate = new DateTimePicker();
            transactionDate.Width = w1;
            transactionDate.Height = h1;
            transactionDate.Format = DateTimePickerFormat.Short;
            transactionDate.Location = new Point(x1, y1);
            transactionDate.Anchor = AnchorStyles.Top;
            transactionDate.Format = DateTimePickerFormat.Custom;
            transactionDate.CustomFormat = "dd/MM/yyyy";
            transactionDate.ValueChanged += transactionDate_ValueChanged;
            panelDetails.PanelWithControls.Controls.Add(transactionDate);

            ComboBox head = new ComboBox();
            head.Width = w2;
            head.Height = h2;
            head.DropDownStyle = ComboBoxStyle.DropDownList;
            head.FlatStyle = FlatStyle.Flat;

            foreach (StaticList staticList in SettingsAndStaticListLoader.HeadList)
            {
                ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                head.Items.Add(comboBoxItem);
            }
            var incomeHead = SettingsAndStaticListLoader.HeadList.Where(t => t.ListItemCode.Equals("head_income")).FirstOrDefault();
            int indexOfIncome = SettingsAndStaticListLoader.HeadList.IndexOf(incomeHead);

            head.SelectedIndex = indexOfIncome;
            head.SelectedIndexChanged += head_SelectedIndexChanged;
            head.Location = new Point(x2, y2);
            head.Anchor = AnchorStyles.Top;
            panelDetails.PanelWithControls.Controls.Add(head);

            ComboBox transactionMode = new ComboBox();
            transactionMode.Width = w3;
            transactionMode.Height = h3;
            transactionMode.DropDownStyle = ComboBoxStyle.DropDownList;
            transactionMode.FlatStyle = FlatStyle.Flat;

            int tempIndex = 0;
            int indexOfChequeTransMode = 0;
            foreach (StaticList staticList in SettingsAndStaticListLoader.TransactionModeList.Where(t => !t.ListItemCode.Equals("transaction_mode_bankdebit") &&
                                                                             !t.ListItemCode.Equals("transaction_mode_pettycashwithdrawal")))
            {
                ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                transactionMode.Items.Add(comboBoxItem);

                if (staticList.ListItemCode.Equals("transaction_mode_cheque"))
                {
                    indexOfChequeTransMode = tempIndex;
                }

                tempIndex++;
            }

            transactionMode.SelectedIndex = indexOfChequeTransMode;
            transactionMode.Location = new Point(x3, y3);
            transactionMode.Anchor = AnchorStyles.Top;
            transactionMode.SelectedIndexChanged += transactionMode_SelectedIndexChanged;
            panelDetails.PanelWithControls.Controls.Add(transactionMode);

            TextBox transactionAmountInINR = new TextBox();
            transactionAmountInINR.Width = w4;
            transactionAmountInINR.Height = h4;
            transactionAmountInINR.Location = new Point(x4, y4);
            transactionAmountInINR.Anchor = AnchorStyles.Top;
            transactionAmountInINR.Leave += transactionAmountInINR_Leave;
            transactionAmountInINR.TextChanged += transactionAmountInINR_TextChanged;
            transactionAmountInINR.TextChanged += this.IsDirtyMarkerMainRow;
            panelDetails.PanelWithControls.Controls.Add(transactionAmountInINR);


            LinkLabel headDetailsLinkLabel = new LinkLabel();
            headDetailsLinkLabel.Width = w5;
            headDetailsLinkLabel.Height = h5;
            headDetailsLinkLabel.Location = new Point(x5, y5);
            headDetailsLinkLabel.Anchor = AnchorStyles.Top;
            headDetailsLinkLabel.TextAlign = ContentAlignment.MiddleCenter;
            headDetailsLinkLabel.LinkClicked += headDetailsLinkLabel_LinkClicked;
            headDetailsLinkLabel.Text = "Choose head details";
            headDetailsLinkLabel.LinkBehavior = LinkBehavior.NeverUnderline;
            //headDetailsLinkLabel.LinkColor = Color.Black;
            headDetailsLinkLabel.TextChanged += this.IsDirtyMarkerMainRow;
            panelDetails.PanelWithControls.Controls.Add(headDetailsLinkLabel);

            CheckBoxComboBox expenseApprover = new CheckBoxComboBox();

            List<ExpenseApprover> tempExpenseApproverList = new List<ExpenseApprover>();
            tempExpenseApproverList.AddRange(SettingsAndStaticListLoader.ExpenseApproverList);
            ListSelectionWrapper<ExpenseApprover> expenseApproverList = new ListSelectionWrapper<ExpenseApprover>(tempExpenseApproverList, "DisplayName");
            expenseApprover.DataSource = expenseApproverList;
            expenseApprover.DisplayMemberSingleItem = "Name";
            expenseApprover.DisplayMember = "NameConcatenated";
            expenseApprover.ValueMember = "Selected";
            expenseApprover.Width = w6;
            expenseApprover.Height = h6;
            expenseApprover.Location = new Point(x6, y6);
            expenseApprover.Anchor = AnchorStyles.Top;
            expenseApprover.DropDownStyle = ComboBoxStyle.DropDownList;
            expenseApprover.Enabled = false; // by default
            expenseApprover.SelectedIndexChanged += IsDirtyMarkerMainRow;
            panelDetails.PanelWithControls.Controls.Add(expenseApprover);


            TextBox invoiceBillNo = new TextBox();
            invoiceBillNo.Width = w7;
            invoiceBillNo.Height = h7;
            invoiceBillNo.Location = new Point(x7, y7);
            invoiceBillNo.Anchor = AnchorStyles.Top;
            invoiceBillNo.TextChanged += this.IsDirtyMarkerMainRow;
            panelDetails.PanelWithControls.Controls.Add(invoiceBillNo);

            // REMOVED PO NUMBER ON 9 JULY 2013 TO GIVE SPACE TO EXPENSE APPROVER :)
            //TextBox poNumber = new TextBox();
            //poNumber.Width = w7;
            //poNumber.Height = h7;
            //poNumber.Location = new Point(x7, y7);
            //poNumber.Anchor = AnchorStyles.Top;
            //poNumber.TextChanged += this.isDirtyMarker;
            //panelDetails.PanelWithControls.Controls.Add(poNumber);

            //TextBox narration = new TextBox();
            //narration.Width = w8;
            //narration.Height = h8;
            //narration.Location = new Point(x8, y8);
            //narration.Anchor = AnchorStyles.Top;
            //panelDetails.PanelWithControls.Controls.Add(narration);

            LinkLabel narration = new LinkLabel();
            narration.Width = w8;
            narration.Height = h8;
            narration.Location = new Point(x8, y8);
            narration.Anchor = AnchorStyles.Top;
            narration.TextAlign = ContentAlignment.MiddleCenter;
            narration.LinkClicked += narration_LinkClicked;
            narration.Text = "Enter Narration";
            narration.LinkBehavior = LinkBehavior.NeverUnderline;
            narration.Tag = null;
            //headDetailsLinkLabel.LinkColor = Color.Black;
            narration.TextChanged += this.IsDirtyMarkerMainRow;
            panelDetails.PanelWithControls.Controls.Add(narration);

            Label receiptVoucherNumber = new Label();
            receiptVoucherNumber.Width = w9;
            receiptVoucherNumber.Height = h9;
            receiptVoucherNumber.Location = new Point(x9, y9);
            receiptVoucherNumber.Anchor = AnchorStyles.Top;
            receiptVoucherNumber.TextAlign = ContentAlignment.MiddleCenter;
            receiptVoucherNumber.TextChanged += this.IsDirtyMarkerMainRow;
            panelDetails.PanelWithControls.Controls.Add(receiptVoucherNumber);

            //reconcile checkbox
            CheckBox reconcileCheckBox = new CheckBox();
            reconcileCheckBox.Location = new Point(x10, y10);
            reconcileCheckBox.Anchor = AnchorStyles.Top;
            reconcileCheckBox.Text = string.Empty;
            reconcileCheckBox.Width = 14;
            reconcileCheckBox.CheckedChanged += reconcileCheckBox_CheckedChanged;
            panelDetails.PanelWithControls.Controls.Add(reconcileCheckBox);
            w10 = reconcileCheckBox.Width;


            // Delete button
            Button mainRowDeleteButton = new Button();
            mainRowDeleteButton.Width = 50;
            mainRowDeleteButton.Height = h9; // could be any of the 'h's since all are the same
            mainRowDeleteButton.Location = new Point(x10 + w10 + 16, y10 - 1); // displacing by 4 on the x axis and by 1 on the y axis;
            mainRowDeleteButton.Anchor = AnchorStyles.Top;
            mainRowDeleteButton.Click += mainRowDeleteButton_Click;

            if (!panelDetails.IsNew)
            {
                mainRowDeleteButton.Text = "Delete";
            }
            else
            {
                mainRowDeleteButton.Text = "Remove Row";
            }


            mainRowDeleteButton.Font = new System.Drawing.Font(FontFamily.GenericSerif, 7);
            panelDetails.PanelWithControls.Controls.Add(mainRowDeleteButton);

            // set data if it is an existing record
            if (panelDetails.DataForPersistence != null)
            {
                TransactionMaster data = (TransactionMaster)panelDetails.DataForPersistence;

                transactionDate.Value = data.TransactionDate;

                int index = 0;
                foreach (ComboBoxItem item in head.Items)
                {
                    if (((StaticList)item.Value).ListItemCode.Equals(data.Head))
                    {
                        head.SelectedIndex = index;
                        break;
                    }

                    index++;
                }

                index = 0;
                foreach (ComboBoxItem item in transactionMode.Items)
                {
                    if (((StaticList)item.Value).ListItemCode.Equals(data.TransactionModeValue))
                    {
                        transactionMode.SelectedIndex = index;
                        break;
                    }

                    index++;
                }

                transactionAmountInINR.Text = data.TransactionAmount.ToString();

                List<TransactionType> temp = GetTransactionType(data.HeadDetailsHierarchyIdList);
                temp = ArrangeItems(temp);
                if (temp.Count > 0)
                {
                    headDetailsLinkLabel.Text = temp.Last().Name;
                    string headDetailsComplete = string.Join("-->", temp.Select(t => t.Name).ToArray());
                    toolTip1.SetToolTip(headDetailsLinkLabel, headDetailsComplete);
                }
                else
                {
                    headDetailsLinkLabel.Text = "Choose head details";
                    toolTip1.SetToolTip(headDetailsLinkLabel, null);
                }

                if (data.Narration != null)
                {
                    narration.Text = data.Narration.Replace(Environment.NewLine, string.Empty);
                    if (narration.Text.Length > 10)
                    {
                        narration.Text = narration.Text.Substring(0, 9);
                    }
                    narration.Tag = data.Narration;
                }

                if (data.VoucherReceiptNumber != 0)
                {
                    receiptVoucherNumber.Text = data.VoucherReceiptPrefix + data.VoucherReceiptNumber.ToString();
                    receiptVoucherNumber.Tag = data.VoucherReceiptNumber;
                }

                if (!string.IsNullOrEmpty(data.InvoiceOrBillNumber))
                {
                    invoiceBillNo.Text = data.InvoiceOrBillNumber;
                }

                if (data.PONumber.HasValue)
                {
                    // REMOVED PO NUMBER ON 9 JULY 2013 TO GIVE SPACE TO EXPENSE APPROVER :)
                    //poNumber.Text = data.PONumber.ToString();
                }

                // disable fields which cannot be edited
                transactionMode.Enabled = false; // transactionMode cannot be edited i.e. cash or cheque
                head.Enabled = false; // head cannot be edited i.e. income/ expense
                if (data.TransactionModeValue.Equals("transaction_mode_cash") &&
                    data.Head.Equals("head_expense"))
                {
                    transactionAmountInINR.Enabled = false;
                }

                // set the reconciled checkbox
                reconcileCheckBox.Checked = data.BankDate.HasValue;
                panelDetails.IsReconciled = data.BankDate.HasValue;

                // set the expense approvers
                if (data.Head.Equals("head_expense"))
                {
                    List<int> expenseApproverIdList = data.ExpenseApproverIdList.GetIntegerListFromSquareBracketedCommaSeparatedString();
                    foreach (var item in expenseApproverList)
                    {
                        if (expenseApproverIdList.Contains(item.Item.Id))
                        {
                            item.Selected = true;
                        }
                        else
                        {
                            item.Selected = false;
                        }
                    }
                }
                else
                {
                    expenseApprover.Enabled = false;
                    expenseApproverList.ForEach(t => t.Selected = false);
                }

                panelDetails.IsAutoApproved = data.IsAutoApproved;
            }

            foreach (Control control in panelDetails.PanelWithControls.Controls)
            {
                control.Tag = panelDetails.Guid;
                control.GotFocus += control_GotFocus;
            }
        }

        

        

        private void control_GotFocus(object sender, EventArgs e)
        {
            Control control = (Control)sender;
            transEntryMainPanel_Click((Panel)control.Parent, null);
        }

        private void CreatePanelChequeDetailsRow(int x1, int y1, int w1, int h1,
                                                int x2, int y2, int w2, int h2,
                                                int x3, int y3, int w3, int h3,
                                                int x4, int y4, int w4, int h4,
                                                int x5, int y5, int w5, int h5,
                                                int x6, int y6, int w6, int h6,
                                                int x7, int y7, int w7, int h7,
                                                int panelX, int panelY, int panelW, int panelH, int offset,
                                                PanelDetails panelDetails)
        {
            //Panel panel = new Panel();
            panelDetails.PanelWithControls = new Panel();
            panelDetails.PanelWithControls.Height = panelH;
            panelDetails.PanelWithControls.Width = panelW;
            panelDetails.PanelWithControls.Location = new Point(panelX, (panelY + offset));
            panelDetails.PanelWithControls.Visible = true;
            panelDetails.PanelWithControls.Anchor = AnchorStyles.Top | AnchorStyles.Left;
            panelDetails.PanelWithControls.BorderStyle = BorderStyle.FixedSingle;

            panelDetails.PanelWithControls.Name = panelDetails.Guid.ToString();
            panelDetails.PanelWithControls.Tag = panelDetails.Guid;

            TextBox chequeNumber = new TextBox();
            chequeNumber.Width = w1;
            chequeNumber.Height = h1;
            chequeNumber.Location = new Point(x1, y1);
            //chequeNumber.TextChanged += IsDirtyMarkerChequeDetailsRow;
            panelDetails.PanelWithControls.Controls.Add(chequeNumber);

            DateTimePicker chequeDate = new DateTimePicker();
            chequeDate.Width = w2;
            chequeDate.Height = h2;
            chequeDate.Format = DateTimePickerFormat.Short;
            chequeDate.Location = new Point(x2, y2);
            chequeDate.Format = DateTimePickerFormat.Custom;
            chequeDate.CustomFormat = "dd/MM/yyyy";
            //chequeDate.ValueChanged += IsDirtyMarkerChequeDetailsRow;
            panelDetails.PanelWithControls.Controls.Add(chequeDate);

            ComboBox chequeStatus = new ComboBox();
            chequeStatus.Width = w3;
            chequeStatus.Height = h3;
            chequeStatus.DropDownStyle = ComboBoxStyle.DropDownList;
            chequeStatus.FlatStyle = FlatStyle.Flat;
            foreach (StaticList staticList in SettingsAndStaticListLoader.ChequeStatusList)
            {
                ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                chequeStatus.Items.Add(comboBoxItem);
            }
            //chequeStatus.SelectedIndexChanged += IsDirtyMarkerChequeDetailsRow;
            chequeStatus.SelectedIndex = 0;
            chequeStatus.Location = new Point(x3, y3);
            panelDetails.PanelWithControls.Controls.Add(chequeStatus);

            TextBox chequeAmount = new TextBox();
            chequeAmount.Width = w4;
            chequeAmount.Height = h4;
            chequeAmount.Location = new Point(x4, y4);
            //chequeAmount.TextChanged += IsDirtyMarkerChequeDetailsRow;
            panelDetails.PanelWithControls.Controls.Add(chequeAmount);

            ComboBox drawnOnBank = new ComboBox();
            drawnOnBank.Width = w5;
            drawnOnBank.Height = h5;
            drawnOnBank.DropDownStyle = ComboBoxStyle.DropDownList;
            drawnOnBank.FlatStyle = FlatStyle.Flat;
            foreach (StaticList staticList in SettingsAndStaticListLoader.BankNameList)
            {
                ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                drawnOnBank.Items.Add(comboBoxItem);
            }
            drawnOnBank.SelectedIndex = 0;
            drawnOnBank.Location = new Point(x5, y5);
            drawnOnBank.GotFocus += drawnOnBank_GotFocus;
            //drawnOnBank.SelectedIndexChanged += IsDirtyMarkerChequeDetailsRow;
            panelDetails.PanelWithControls.Controls.Add(drawnOnBank);

            TextBox narration = new TextBox();
            narration.Width = w6;
            narration.Height = h6;
            narration.Location = new Point(x6, y6);
            //narration.TextChanged += IsDirtyMarkerChequeDetailsRow;  
            panelDetails.PanelWithControls.Controls.Add(narration);

            Button viewUploadImage = new Button();
            viewUploadImage.Width = w7;
            viewUploadImage.Height = h7;
            viewUploadImage.Text = "View/ Upload";
            viewUploadImage.Location = new Point(x7, y7);
            viewUploadImage.Click += viewUploadImage_Click;
            panelDetails.PanelWithControls.Controls.Add(viewUploadImage);


            // Delete button
            Button chequeDetailsRowDeleteButton = new Button();
            chequeDetailsRowDeleteButton.Width = 68;
            chequeDetailsRowDeleteButton.Height = h7; // could be any of the 'h's since all are the same
            chequeDetailsRowDeleteButton.Location = new Point(x7 + w7 + 2, y7 - 1); // displacing by 5 on the x axis and by 1 on the y axis;
            chequeDetailsRowDeleteButton.Click += chequeDetailsRowDeleteButton_Click;

            if (!panelDetails.IsNew)
            {
                chequeDetailsRowDeleteButton.Text = "Delete";
            }
            else
            {
                chequeDetailsRowDeleteButton.Text = "Remove Row";
            }

            chequeDetailsRowDeleteButton.Font = new System.Drawing.Font(FontFamily.GenericSerif, 7);


            // set data if it is an existing record
            if (panelDetails.DataForPersistence != null)
            {
                TransactionMasterChequeDetail data = (TransactionMasterChequeDetail)panelDetails.DataForPersistence;
                chequeNumber.Text = data.ChequeNumber.ToString();
                chequeDate.Value = data.ChequeDate;

                int index = 0;
                foreach (ComboBoxItem item in chequeStatus.Items)
                {
                    if (((StaticList)item.Value).ListItemCode.Equals(data.ChequeStatus))
                    {
                        chequeStatus.SelectedIndex = index;
                        break;
                    }

                    index++;
                }

                chequeAmount.Text = data.ChequeAmount.ToString();

                index = 0;
                foreach (ComboBoxItem item in drawnOnBank.Items)
                {
                    if (((StaticList)item.Value).ListItemCode.Equals(data.ChequeDrawnOnBank))
                    {
                        drawnOnBank.SelectedIndex = index;
                        break;
                    }

                    index++;
                }

                narration.Text = data.Narration;
            }

            foreach (Control control in panelDetails.PanelWithControls.Controls)
            {
                control.Tag = panelDetails.Guid;
            }
        }

        //void chequeStatus_SelectedIndexChanged(object sender, EventArgs e)
        //{
        //    ComboBox chequeStatus = (ComboBox)sender;
        //    Panel parent = (Panel)chequeStatus.Parent;
        //    Guid chequePanelGuid = (Guid)parent.Tag;
        //    if (chequeDetailsPanelMap.ContainsKey(chequePanelGuid))
        //    {
        //        PanelDetails panelDetails = (PanelDetails)chequeDetailsPanelMap[chequePanelGuid];
        //        panelDetails.IsDirty = true;
        //    }
        //}

        //private void chequeDate_ValueChanged(object sender, EventArgs e)
        //{
        //    DateTimePicker chequeDate = (DateTimePicker)sender;
        //    Panel parent = (Panel)chequeDate.Parent;
        //    Guid chequePanelGuid = (Guid)parent.Tag;
        //    if (chequeDetailsPanelMap.ContainsKey(chequePanelGuid))
        //    {
        //        PanelDetails panelDetails = (PanelDetails)chequeDetailsPanelMap[chequePanelGuid];
        //        panelDetails.IsDirty = true;
        //    }
        //}

        private void drawnOnBank_GotFocus(object sender, EventArgs e)
        {
            ComboBox comboBox = (ComboBox)sender;
            comboBox.SelectedIndex = 0; // setting the default

            try
            {
                Guid guid = (Guid)comboBox.Tag;
                PanelDetails chequeDetailsPanelDetails = chequeDetailsPanelMap[guid];
                PanelDetails parentTransactionMasterPanelDetails = chequeDetailsPanelDetails.ParentTransactionMasterPanelDetails;

                ComboBox head = (ComboBox)parentTransactionMasterPanelDetails.PanelWithControls.Controls[1];
                ComboBoxItem headSelectedItem = (ComboBoxItem)head.SelectedItem;
                StaticList headSelectedStaticList = (StaticList)headSelectedItem.Value;

                ComboBox transactionMode = (ComboBox)parentTransactionMasterPanelDetails.PanelWithControls.Controls[2];
                ComboBoxItem transactionModeSelectedItem = (ComboBoxItem)transactionMode.SelectedItem;
                StaticList transactionModeSelectedStaticList = (StaticList)transactionModeSelectedItem.Value;

                comboBox.Items.Clear();

                if ((headSelectedStaticList.ListItemCode.Equals("head_expense") && transactionModeSelectedStaticList.ListItemCode.Equals("transaction_mode_cheque")) ||
                    (headSelectedStaticList.ListItemCode.Equals("head_expense") && transactionModeSelectedStaticList.ListItemCode.Equals("transaction_mode_pettycashwithdrawal")))
                {
                    //string defaultExpenseBankAccount = AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.DefaultExpenseBankAccount];
                    string defaultExpenseBankAccount = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.DefaultExpenseBankAccount);
                    int index = 0;
                    int selectedIdexToUse = 0;
                    foreach (StaticList staticList in SettingsAndStaticListLoader.BankAccountsStaticList)
                    {
                        ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                        comboBox.Items.Add(comboBoxItem);

                        if (staticList.ListItemCode.Equals(defaultExpenseBankAccount))
                        {
                            selectedIdexToUse = index;
                        }
                        index++;
                    }

                    comboBox.SelectedIndex = selectedIdexToUse;
                }
                else
                {
                    //string defaultIncomeDepositBankAccount = AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.DefaultIncomeDepositBankAccount];
                    string defaultIncomeDepositBankAccount = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.DefaultIncomeDepositBankAccount);
                    int index = 0;
                    int selectedIdexToUse = 0;
                    foreach (StaticList staticList in SettingsAndStaticListLoader.BankNameList)
                    {
                        ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                        comboBox.Items.Add(comboBoxItem);

                        if (staticList.ListItemCode.Equals(defaultIncomeDepositBankAccount))
                        {
                            selectedIdexToUse = index;
                        }
                        index++;
                    }

                    comboBox.SelectedIndex = selectedIdexToUse;
                }

                if (chequeDetailsPanelDetails.DataForPersistence != null)
                {
                    TransactionMasterChequeDetail data = (TransactionMasterChequeDetail)chequeDetailsPanelDetails.DataForPersistence;
                    int index = 0;
                    foreach (ComboBoxItem item in comboBox.Items)
                    {
                        if (((StaticList)item.Value).ListItemCode.Equals(data.ChequeDrawnOnBank))
                        {
                            comboBox.SelectedIndex = index;
                            break;
                        }

                        index++;
                    }
                }
                else
                {


                }

            }
            catch { }
        }

        private void viewUploadImage_Click(object sender, EventArgs e)
        {
            Button button = (Button)sender;
            PanelDetails panelDetails = null;
            string existingFilePath = string.Empty;
            if (button.Tag != null)
            {
                Guid panelGuid = (Guid)button.Tag;
                if (chequeDetailsPanelMap.ContainsKey(panelGuid))
                {
                    panelDetails = chequeDetailsPanelMap[panelGuid];
                    if (panelDetails.DataForPersistence != null)
                    {
                        TransactionMasterChequeDetail transactionMasterChequeDetail =
                                                    (TransactionMasterChequeDetail)panelDetails.DataForPersistence;

                        if (!string.IsNullOrEmpty(transactionMasterChequeDetail.ScannedChequeImagePath) &&
                            !string.IsNullOrEmpty(SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ScannedImageLocation)))
                        {
                            existingFilePath = Path.Combine(SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ScannedImageLocation),
                                                                transactionMasterChequeDetail.ScannedChequeImagePath);
                        }
                    }
                }
            }

            ScanAndPrint scanAndPrintForm = new ScanAndPrint(existingFilePath);
            scanAndPrintForm.ShowDialog();

            if (panelDetails != null)
            {
                panelDetails.SelectedFilePathForSaving = scanAndPrintForm.SelectedFilePath;
                panelDetails.SelectedDocTypeForSaving = scanAndPrintForm.SelectedDocType;
            }
        }

        private void buttonSaveTransactionEntries_Click(object sender, EventArgs e)
        {
            if (mainPanelMap.Values.Count == 0)
            {
                MessageBox.Show("You have not entered any data to be saved.", "Nothing to save", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.buttonAddRowMain_Click(null, null);
                return;
            }

            List<TransactionMaster> transactionMasterListForSaveAndUpdate = new List<TransactionMaster>();
            List<TransactionMasterChequeDetail> newChequeDetailsForExistingTransMasterList = new List<TransactionMasterChequeDetail>();

            int chequeDetailsNotEntered = 0;

            try
            {
                string defaultExpenseBankAccount = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.DefaultExpenseBankAccount);
                string defaultIncomeDepositBankAccount = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.DefaultIncomeDepositBankAccount);

                foreach (PanelDetails panelDetails in mainPanelMap.Values)
                {
                    TransactionMaster transactionMaster = Translator.ToTransactionMasterDB(panelDetails);
                    if (transactionMaster.IsActive && transactionMaster.TransactionModeValue.Equals("transaction_mode_cheque") &&
                       (panelDetails.ChildrenChequeDetails.Count == 0 || panelDetails.ChildrenChequeDetails.Where(t => !t.IsDeleted).Count() == 0))
                    {
                        chequeDetailsNotEntered++;
                        continue;
                    }

                    decimal totalAmount = transactionMaster.TransactionAmount;
                    decimal chequeTotal = 0;
                    bool chequeDetailsAvailable = false;
                    foreach (PanelDetails childChequeDetails in panelDetails.ChildrenChequeDetails)
                    {
                        if ((childChequeDetails.IsNew && childChequeDetails.IsDeleted) || childChequeDetails.IsParentDeleted)
                        {
                            continue;
                        }

                        TransactionMasterChequeDetail chequeDetails = Translator.ToTransactionMasterChequeDetailsDB(childChequeDetails);
                        if (transactionMaster.Id == 0)
                        {
                            transactionMaster.TransactionMasterChequeDetails.Add(chequeDetails);
                        }
                        else if (chequeDetails.Id == 0)
                        {
                            chequeDetails.TransactionMasterId = transactionMaster.Id;
                            newChequeDetailsForExistingTransMasterList.Add(chequeDetails);
                        }
                        chequeDetailsAvailable = true;
                        chequeTotal = chequeTotal + chequeDetails.ChequeAmount;
                    }

                    if (chequeDetailsAvailable && chequeTotal != totalAmount)
                    {
                        throw new ValidationException("The total amount entered in the main transaction row does not match the amount entered in the cheque details row. Please correct all such occurences.");
                    }

                    // set the transaction bank account
                    if (transactionMaster.Head.Equals("head_expense"))
                    {
                        if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                        {
                            transactionMaster.BankAccountsId = null;
                        }
                        // it does not matter if the transaction is new or existing
                        // the bank account must match the cheque drawn on bank ALWAYS
                        else if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cheque") ||
                            transactionMaster.TransactionModeValue.Equals("transaction_mode_pettycashwithdrawal"))
                        {
                            string chequeDrawnOnBank = transactionMaster.TransactionMasterChequeDetails.FirstOrDefault().ChequeDrawnOnBank;
                            BankAccount requiredBankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.BankName.Equals(chequeDrawnOnBank)).FirstOrDefault();
                            if (requiredBankAccount != null)
                            {
                                transactionMaster.BankAccountsId = requiredBankAccount.Id;
                            }
                        }
                        else
                        {
                            // set the bank account for only new expense transactions
                            // when it is neither cheque or pettycash withdrawal.
                            // we do not want to change it for existing transactions because they may be already set
                            if (transactionMaster.Id == 0)
                            {
                                if (!panelDetails.BankAccountsId.HasValue)
                                {
                                    BankAccount requiredBankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.BankName.Equals(defaultExpenseBankAccount)).FirstOrDefault();
                                    if (requiredBankAccount != null)
                                    {
                                        transactionMaster.BankAccountsId = requiredBankAccount.Id;
                                    }
                                    else
                                    {
                                        transactionMaster.BankAccountsId = SettingsAndStaticListLoader.BankAccountList[0].Id;
                                    }
                                }
                                else
                                {
                                    transactionMaster.BankAccountsId = panelDetails.BankAccountsId;
                                }
                            }
                        }
                    }
                    else
                    {
                        // set the bank account for only new income transactions.
                        // we do not want to change it for existing transactions because they may be already set
                        if (transactionMaster.Id == 0)
                        {
                            if (!panelDetails.BankAccountsId.HasValue)
                            {
                                BankAccount requiredBankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.BankName.Equals(defaultIncomeDepositBankAccount)).FirstOrDefault();
                                if (requiredBankAccount != null)
                                {
                                    transactionMaster.BankAccountsId = requiredBankAccount.Id;
                                }
                                else
                                {
                                    transactionMaster.BankAccountsId = SettingsAndStaticListLoader.BankAccountList[0].Id;
                                }
                            }
                            else
                            {
                                transactionMaster.BankAccountsId = panelDetails.BankAccountsId;
                            }
                        }
                    }

                    transactionMasterListForSaveAndUpdate.Add(transactionMaster);
                }

                if (chequeDetailsNotEntered > 0)
                {
                    throw new ValidationException("Cheque details have not been entered at {0} place(s). You must enter cheque details if the selected transaction mode is cheque. Please correct all such instances.");
                }

                bool pettyCashViewRefreshNeeded = false;
                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TimeSpan(0, 10, 0)))
                {
                    #region Old Code. Now moved to the translator
                    //// set default income and expense bank accounts
                    //// default expense bank account will be set using the default value only for non-cheque transactions
                    //// for cheque expense transactions, the cheque's drawn on bank would be set and will NOT be editable in the grid view.
                    ////string defaultExpenseBankAccount = AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.DefaultExpenseBankAccount];
                    //string defaultExpenseBankAccount = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.DefaultExpenseBankAccount);
                    ////string defaultIncomeDepositBankAccount = AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.DefaultIncomeDepositBankAccount];
                    //string defaultIncomeDepositBankAccount = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.DefaultIncomeDepositBankAccount);
                    //foreach (TransactionMaster transactionMaster in transactionMasterListForSaveAndUpdate.Where(t => t.IsActive))
                    //{
                    //    if (transactionMaster.Head.Equals("head_expense"))
                    //    {
                    //        if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cash"))
                    //        {
                    //            transactionMaster.BankAccountsId = null;
                    //        }
                    //        else if (transactionMaster.TransactionModeValue.Equals("transaction_mode_cheque") ||
                    //           transactionMaster.TransactionModeValue.Equals("transaction_mode_pettycashwithdrawal"))
                    //        {
                    //            string chequeDrawnOnBank = transactionMaster.TransactionMasterChequeDetails.FirstOrDefault().ChequeDrawnOnBank;
                    //            BankAccount requiredBankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.BankName.Equals(chequeDrawnOnBank)).FirstOrDefault();
                    //            if (requiredBankAccount != null)
                    //            {
                    //                transactionMaster.BankAccountsId = requiredBankAccount.Id;
                    //            }
                    //        }
                    //        else
                    //        {
                    //            BankAccount requiredBankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.BankName.Equals(defaultExpenseBankAccount)).FirstOrDefault();
                    //            if (requiredBankAccount != null)
                    //            {
                    //                transactionMaster.BankAccountsId = requiredBankAccount.Id;
                    //            }
                    //            else
                    //            {
                    //                transactionMaster.BankAccountsId = SettingsAndStaticListLoader.BankAccountList[0].Id;
                    //            }
                    //        }
                    //    }
                    //    else
                    //    {
                    //        //if(tran)
                    //        BankAccount requiredBankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.BankName.Equals(defaultIncomeDepositBankAccount)).FirstOrDefault();
                    //        if (requiredBankAccount != null)
                    //        {
                    //            transactionMaster.BankAccountsId = requiredBankAccount.Id;
                    //        }
                    //        else
                    //        {
                    //            transactionMaster.BankAccountsId = SettingsAndStaticListLoader.BankAccountList[0].Id;
                    //        }
                    //    }
                    //}

                    #endregion Old Code. Now moved to the translator

                    pettyCashViewRefreshNeeded = transactionMasterListForSaveAndUpdate.Any(t => t.IsActive && 
                                                                   t.Head.Equals("head_expense") &&
                                                                   (
                                                                     t.TransactionModeValue.Equals("transaction_mode_cash") ||
                                                                     t.TransactionModeValue.Equals("transaction_mode_pettycashwithdrawal")
                                                                   ));
                    this.dataAccessHandlerCommonInstance.SaveTransactionMasterList(transactionMasterListForSaveAndUpdate,
                                                                SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ScannedImageLocation),
                                                                MainForm.Context);
                    
                    // this will never be used now since there cannot be more than one cheque details entry per transaction
                    // should be removed in due course.. when?? :D :D 
                    this.dataAccessHandlerCommonInstance.SaveNewTransactionMasterChequeDetailList(newChequeDetailsForExistingTransMasterList,
                                                                               SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ScannedImageLocation),
                                                                               MainForm.Context);

                    this.dataAccessHandlerCommonInstance.UpdateBankAccountDetailsAndStatistics(MainForm.Context);

                    scope.Complete();
                }

                UpdatePettyCashLimit();

                ClearMainTransactionEntryScrollPanel();
                ClearChequeDetailsPanel();
                mainPanelMap.Clear();
                chequeDetailsPanelMap.Clear();


                MessageBox.Show("Your data was saved sucessfully", "Save successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this._resultRefreshNeededBankStatementsView = true;
                this._resultRefreshNeededReconcileView = true;
                if (pettyCashViewRefreshNeeded)
                {
                    this._loadPettyCashView = true;
                }


                this.buttonAddRowMain.PerformClick();
            }
            catch (ValidationException vex)
            {
                MessageBox.Show(string.Format("There was a problem saving your data. {0}", vex.Message), "Save failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            catch (DALException dex)
            {
                MessageBox.Show(string.Format("There was a problem saving your data. {0}", dex.Message), "Save failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            catch (FileCopyException fex)
            {
                MessageBox.Show(string.Format("{0}. However, the transactions were saved. Please contact your administrator for fix this problem. You may try uploading the documents again after the problems have been fixed.", fex.Message), "File upload failed", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            catch (Exception ex)
            {
                MessageBox.Show("There was a problem saving your data. \r\n Please view the log file and share it with your administrator.", "Save failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

       

        private void reconcileCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox checkBox = (CheckBox)sender;
            Panel panel = (Panel)checkBox.Parent;
            Guid parentPanelGuid = (Guid)panel.Tag;
            if (mainPanelMap.ContainsKey(parentPanelGuid))
            {
                PanelDetails panelDetails = (PanelDetails)mainPanelMap[parentPanelGuid];
                panelDetails.IsReconciled = checkBox.Checked;
            }

        }

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            this.mainPanelMap.Clear();
            this.chequeDetailsPanelMap.Clear();
            this.panelForScrollMain.Controls.Clear();
            this.panelForChequeDetailsScroll.Controls.Clear();
            this.buttonAddRowMain.PerformClick();
        }

        // important event handlers
        private void head_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox head = (ComboBox)sender;
            Panel parent = (Panel)head.Parent;
            LinkLabel linkLabel = (LinkLabel)parent.Controls[4];
            linkLabel.Text = "Choose head details";
            toolTip1.SetToolTip(linkLabel, null);

            PanelDetails panelDetails = null;

            if (mainPanelMap.ContainsKey((Guid)parent.Tag))
            {
                panelDetails = mainPanelMap[(Guid)parent.Tag];
                panelDetails.SelectedTransactionTypes.Clear();
                panelDetails.IsDirty = true;
            }

            // retain only those transaction modes which are relevant to the head selected i.e. income or expense.
            ComboBoxItem selectedItem = (ComboBoxItem)head.SelectedItem;
            if (selectedItem != null && selectedItem.Value != null)
            {
                StaticList staticListSelected = (StaticList)selectedItem.Value;
                ComboBox transactionMode = (ComboBox)parent.Controls[2];
                CheckBoxComboBox expenseApprovers = (CheckBoxComboBox)parent.Controls[5];
                transactionMode.Items.Clear();
                int index = 0;
                bool stopIncrementing = false;
                if (staticListSelected.ListItemCode.Equals("head_expense"))
                {
                    foreach (StaticList staticList in SettingsAndStaticListLoader.TransactionModeList.Where(t => !t.ListItemCode.Equals("transaction_mode_bankcredit")))
                    {
                        ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                        transactionMode.Items.Add(comboBoxItem);

                        if (staticList.ListItemCode.Equals("transaction_mode_cheque"))
                        {
                            stopIncrementing = true;
                        }

                        if (!stopIncrementing)
                        {
                            index++;
                        }
                    }

                    expenseApprovers.Enabled = true;
                }
                else
                {
                    foreach (StaticList staticList in SettingsAndStaticListLoader.TransactionModeList.Where(t => !t.ListItemCode.Equals("transaction_mode_bankdebit") &&
                                                                                     !t.ListItemCode.Equals("transaction_mode_pettycashwithdrawal")))
                    {
                        ComboBoxItem comboBoxItem = new ComboBoxItem(staticList.ListItemValue, staticList);
                        transactionMode.Items.Add(comboBoxItem);

                        if (staticList.ListItemCode.Equals("transaction_mode_cheque"))
                        {
                            stopIncrementing = true;
                        }

                        if (!stopIncrementing)
                        {
                            index++;
                        }
                    }

                    // clear and disable expense approvers
                    expenseApprovers.CheckBoxItems.ForEach(t => t.Checked = false);
                    expenseApprovers.Enabled = false;
                }


                transactionMode.SelectedIndex = index;

                SetChequeRowDetailsPerParentHeadAndMode(panelDetails);
            }
        }

        // enforce or remove the cheque row based on the transction mode selected
        private void transactionMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox transactionMode = (ComboBox)sender;
            Panel parent = (Panel)transactionMode.Parent;
            Guid parentPanelGuid = (Guid)parent.Tag;
            PanelDetails panelDetails = null;
            if (mainPanelMap.ContainsKey(parentPanelGuid))
            {
                panelDetails = (PanelDetails)mainPanelMap[parentPanelGuid];
                panelDetails.IsDirty = true;
                ComboBoxItem selectedItem = (ComboBoxItem)transactionMode.SelectedItem;
                if (selectedItem.Value != null)
                {
                    StaticList staticList = (StaticList)selectedItem.Value;
                    if (!staticList.ListItemCode.Equals("transaction_mode_cheque") &&
                        !staticList.ListItemCode.Equals("transaction_mode_pettycashwithdrawal"))
                    {
                        panelDetails.ChildrenChequeDetails.Clear();
                        this.panelForChequeDetailsScroll.Controls.Clear();
                    }
                    else if (staticList.ListItemCode.Equals("transaction_mode_cheque") ||
                             staticList.ListItemCode.Equals("transaction_mode_pettycashwithdrawal"))
                    {
                        if (this.panelForChequeDetailsScroll.Controls.Count == 0)
                        {
                            //this.buttonAddDetailsRow.PerformClick();
                            buttonAddDetailsRow_Click(null, null);
                        }
                    }

                    if (staticList.ListItemCode.Equals("transaction_mode_bankcredit") ||
                             staticList.ListItemCode.Equals("transaction_mode_bankdebit"))
                    {
                        if (panelDetails.SelectedTransactionTypes.Count > 0 && !panelDetails.SelectedTransactionTypes[1].Name.ToLower().Equals("bank"))
                        {
                            LinkLabel linkLabel = (LinkLabel)parent.Controls[4];
                            linkLabel.Text = "Choose head details";
                            toolTip1.SetToolTip(linkLabel, null);
                            panelDetails.SelectedTransactionTypes.Clear();
                        }
                    }
                    else
                    {
                        if (panelDetails.SelectedTransactionTypes.Count > 0 && panelDetails.SelectedTransactionTypes[1].Name.ToLower().Equals("bank"))
                        {
                            LinkLabel linkLabel = (LinkLabel)parent.Controls[4];
                            linkLabel.Text = "Choose head details";
                            toolTip1.SetToolTip(linkLabel, null);
                            panelDetails.SelectedTransactionTypes.Clear();
                        }
                    }
                }

                SetChequeRowDetailsPerParentHeadAndMode(panelDetails);
            }
        }

        private void narration_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            LinkLabel linkLabel = (LinkLabel)sender;

            Panel parent = (Panel)linkLabel.Parent;
            Guid parentPanelGuid = (Guid)parent.Tag;
            string existingNarration = string.Empty;
            PanelDetails panelDetails = null;

            TransactionMaster transactionMaster = null;
            if (mainPanelMap.ContainsKey(parentPanelGuid))
            {
                panelDetails = (PanelDetails)mainPanelMap[parentPanelGuid];
                transactionMaster = (TransactionMaster)panelDetails.DataForPersistence;
                if (transactionMaster != null && !string.IsNullOrWhiteSpace(transactionMaster.Narration))
                {
                    existingNarration = transactionMaster.Narration;
                }
                else
                {
                    existingNarration = panelDetails.ProvidedNarration;
                }
            }

            NarrationDialog narration = new NarrationDialog(existingNarration, false);
            narration.StartPosition = FormStartPosition.CenterParent;
            narration.ShowDialog();
            linkLabel.Tag = narration.GetNarration();
            if (panelDetails != null)
            {
                panelDetails.ProvidedNarration = narration.GetNarration();
                if (transactionMaster != null)
                {
                    transactionMaster.Narration = narration.GetNarration();
                }
            }

            if (!string.IsNullOrEmpty(narration.GetNarration()))
            {
                linkLabel.Text = narration.GetNarration().Replace(Environment.NewLine, string.Empty);
                if (linkLabel.Text.Length > 15)
                {
                    linkLabel.Text = linkLabel.Text.Substring(0, 14);
                }
            }
            else
            {
                linkLabel.Text = "Enter Narration";
            }

        }

        private void headDetailsLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            LinkLabel linkLabel = (LinkLabel)sender;
            Panel parent = (Panel)linkLabel.Parent;
            ComboBox transactionMode = (ComboBox)parent.Controls[2];
            ComboBoxItem selectedItem = (ComboBoxItem)transactionMode.SelectedItem;
            StaticList selectedStaticList = (StaticList)selectedItem.Value;
            TransactionTypeTreeViewForm transactionTypeTreeViewForm = null;
            if (selectedStaticList.ListItemCode.Equals("transaction_mode_bankcredit") ||
                selectedStaticList.ListItemCode.Equals("transaction_mode_bankdebit"))
            {
                transactionTypeTreeViewForm = new TransactionTypeTreeViewForm(true, false, false);
            }
            else
            {
                transactionTypeTreeViewForm = new TransactionTypeTreeViewForm(false, false, false);
            }

            if (currentGrayPanel != null)
            {
                ComboBox head = (ComboBox)currentGrayPanel.Controls[1];
                List<string> temp = new List<string>() { head.SelectedItem.ToString().ToLower() };
                transactionTypeTreeViewForm.CreateTreeView(temp, true, true);
            }
            else
            {
                transactionTypeTreeViewForm.CreateTreeView(new List<string>(), true, true);
            }

            DialogResult dr = transactionTypeTreeViewForm.ShowDialog();

            while (dr == System.Windows.Forms.DialogResult.Retry && transactionTypeTreeViewForm.GetSelectedTransactionTypes().Count < 2)
            {
                //MessageBox.Show("Please choose a valid head other than the root, Income and Expense", "Choose valid head", MessageBoxButtons.OK, MessageBoxIcon.Information);
                dr = transactionTypeTreeViewForm.ShowDialog();
            }

            Guid parentPanelGuid = (Guid)parent.Tag;

            if (mainPanelMap.ContainsKey(parentPanelGuid))
            {
                PanelDetails panelDetails = mainPanelMap[parentPanelGuid];
                var selectedTransactionTypes = transactionTypeTreeViewForm.GetSelectedTransactionTypes();
                if (selectedTransactionTypes.Count > 0)
                {
                    panelDetails.SelectedTransactionTypes.Clear();
                    panelDetails.SelectedTransactionTypes.AddRange(transactionTypeTreeViewForm.GetSelectedTransactionTypes());
                    linkLabel.Text = transactionTypeTreeViewForm.GetSelectedShortText();
                    toolTip1.SetToolTip(linkLabel, transactionTypeTreeViewForm.GetSelectedFullText());
                    SetDefaultValuesParentRow(selectedTransactionTypes.Last(), panelDetails);
                    SetDefaultValuesChequeRow(selectedTransactionTypes.Last(), panelDetails);
                }
                else if (selectedTransactionTypes.Count == 0 && panelDetails.SelectedTransactionTypes.Count == 0)
                {
                    linkLabel.Text = "Choose head details";
                    toolTip1.SetToolTip(linkLabel, null);
                    panelDetails.SelectedTransactionTypes.Clear();
                }
            }
        }

        private void SetDefaultValuesChequeRow(TransactionType leafNodeSelected, PanelDetails mainRowPanelDetails)
        {
            HeadDefaultValue headDefaultValue = SettingsAndStaticListLoader.HeadDefaultValueList.Where(t => t.TransactionTypeId.Equals(leafNodeSelected.Id)).FirstOrDefault();

            if (mainRowPanelDetails == null || mainRowPanelDetails.ChildrenChequeDetails.Count == 0 || headDefaultValue == null)
            {
                return;
            }

            PanelDetails chequeDetails = mainRowPanelDetails.ChildrenChequeDetails[mainRowPanelDetails.ChildrenChequeDetails.Count - 1];
            if (chequeDetails != null)
            {
                // get the last cheque row
                TextBox chequeAmountTextBox = (TextBox)chequeDetails.PanelWithControls.Controls[3];
                chequeAmountTextBox.Text = headDefaultValue.Amount.ToString();

                ComboBox head = (ComboBox)mainRowPanelDetails.PanelWithControls.Controls[1];
                ComboBoxItem selectedItem = (ComboBoxItem)head.SelectedItem;
                StaticList selectedStatisList = (StaticList)selectedItem.Value;
                if (selectedStatisList.ListItemCode.Equals("head_expense"))
                {
                    ComboBox drawnOnBank = (ComboBox)chequeDetails.PanelWithControls.Controls[4];
                    int index = 0;
                    foreach (ComboBoxItem item in drawnOnBank.Items)
                    {
                        StaticList staticList = (StaticList)item.Value;
                        if (staticList != null && staticList.ListItemCode.Equals(headDefaultValue.BankName))
                        {
                            drawnOnBank.SelectedIndex = index;
                            break;
                        }

                        index++;
                    }
                }
            }
        }

        private void SetDefaultValuesParentRow(TransactionType leafNodeSelected, PanelDetails mainRowPanelDetails)
        {
            if (!mainRowPanelDetails.IsNew)
            {
                return;
            }

            HeadDefaultValue headDefaultValue = SettingsAndStaticListLoader.HeadDefaultValueList.Where(t => t.TransactionTypeId.Equals(leafNodeSelected.Id)).FirstOrDefault();
            if (headDefaultValue != null && mainRowPanelDetails != null)
            {
                
                if (!string.IsNullOrEmpty(headDefaultValue.TransactionModeValue))
                {
                    ComboBox transactionMode = (ComboBox)mainRowPanelDetails.PanelWithControls.Controls[2];
                    int index = 0;
                    foreach (ComboBoxItem item in transactionMode.Items)
                    {
                        if (((StaticList)item.Value).ListItemCode.Equals(headDefaultValue.TransactionModeValue))
                        {
                            transactionMode.SelectedIndex = index;
                            break;
                        }
                        index++;
                    }
                }

                if (headDefaultValue.Amount.HasValue)
                {
                    TextBox amountTextBox = (TextBox)mainRowPanelDetails.PanelWithControls.Controls[3];
                    amountTextBox.Text = headDefaultValue.Amount.ToString();
                }

                if (!string.IsNullOrEmpty(headDefaultValue.ExpenseApproverIdList))
                {
                    CheckBoxComboBox expenseApproverComboBox = (CheckBoxComboBox)mainRowPanelDetails.PanelWithControls.Controls[5];
                    ListSelectionWrapper<ExpenseApprover> expenseApproverList = (ListSelectionWrapper<ExpenseApprover>)expenseApproverComboBox.DataSource;
                    List<int> expenseApproverIdList = headDefaultValue.ExpenseApproverIdList.GetIntegerListFromSquareBracketedCommaSeparatedString();
                    foreach (var item in expenseApproverList)
                    {
                        if (expenseApproverIdList.Contains(item.Item.Id))
                        {
                            item.Selected = true;
                        }
                        else
                        {
                            item.Selected = false;
                        }
                    }

                    expenseApproverComboBox.Focus();
                }

                if (headDefaultValue.IsAutoApproved.HasValue)
                {
                    mainRowPanelDetails.IsAutoApproved = true;
                }

                if (!string.IsNullOrEmpty(headDefaultValue.Narration))
                {
                    LinkLabel narrationLinkLabel = (LinkLabel)mainRowPanelDetails.PanelWithControls.Controls[7];
                    narrationLinkLabel.Tag = headDefaultValue.Narration;
                    mainRowPanelDetails.ProvidedNarration = headDefaultValue.Narration;
                    narrationLinkLabel.Text = headDefaultValue.Narration.Replace(Environment.NewLine, string.Empty);
                    if (narrationLinkLabel.Text.Length > 15)
                    {
                        narrationLinkLabel.Text = narrationLinkLabel.Text.Substring(0, 14);
                    }
                }

                if (!string.IsNullOrEmpty(headDefaultValue.BankName))
                {
                    BankAccount requiredBankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.BankName.Equals(headDefaultValue.BankName)).FirstOrDefault();
                    if (requiredBankAccount != null)
                    {
                        mainRowPanelDetails.BankAccountsId = requiredBankAccount.Id;
                    }
                }

            }
        }
        
        private void transactionDate_ValueChanged(object sender, EventArgs e)
        {
            DateTimePicker transactionDate = (DateTimePicker)sender;
            Panel parent = (Panel)transactionDate.Parent;
            Guid parentPanelGuid = (Guid)parent.Tag;
            if (mainPanelMap.ContainsKey(parentPanelGuid))
            {
                PanelDetails panelDetails = (PanelDetails)mainPanelMap[parentPanelGuid];
                if (panelDetails.ChildrenChequeDetails.Count > 0)
                {
                    //getting the last cheque row
                    PanelDetails chequeDetailsPanel = panelDetails.ChildrenChequeDetails[panelDetails.ChildrenChequeDetails.Count - 1];
                    if (chequeDetailsPanel.PanelWithControls != null && chequeDetailsPanel.PanelWithControls.Controls.Count > 1)
                    {
                        DateTimePicker chequeDate = (DateTimePicker)chequeDetailsPanel.PanelWithControls.Controls[1];
                        chequeDate.Value = transactionDate.Value;
                    }

                }

                panelDetails.IsDirty = true;
            }
        }

        private void IsDirtyMarkerMainRow(object sender, EventArgs e)
        {
            try
            {
                Control control = (Control)sender;
                Panel parent = (Panel)control.Parent;
                Guid parentPanelGuid = (Guid)parent.Tag;
                if (mainPanelMap.ContainsKey(parentPanelGuid))
                {
                    PanelDetails panelDetails = (PanelDetails)mainPanelMap[parentPanelGuid];
                    panelDetails.IsDirty = true;
                }
            }
            catch { }
        }

        private void IsDirtyMarkerChequeDetailsRow(object sender, EventArgs e)
        {
            try
            {
                Control control = (Control)sender;
                Panel parent = (Panel)control.Parent;
                Guid chequeDetailsPanelGuid = (Guid)parent.Tag;
                if (chequeDetailsPanelMap.ContainsKey(chequeDetailsPanelGuid))
                {
                    PanelDetails panelDetails = (PanelDetails)chequeDetailsPanelMap[chequeDetailsPanelGuid];
                    panelDetails.IsDirty = true;
                }
            }
            catch { }
        }

        private void transactionAmountInINR_Leave(object sender, EventArgs e)
        {
            //TextBox amountTextBox = (TextBox)sender;
            //Guid panelGuid = (Guid)amountTextBox.Tag;
            //if (mainPanelMap.ContainsKey(panelGuid))
            //{
            //    PanelDetails panelDetails = mainPanelMap[panelGuid];
            //    foreach (PanelDetails childPanelDetails in panelDetails.ChildrenChequeDetails)
            //    {
            //        try
            //        {
            //            TextBox chequeTextBox =
            //                (TextBox)childPanelDetails.PanelWithControls.Controls[3];
            //            chequeTextBox.Text = amountTextBox.Text;
            //        }
            //        catch { }
            //    }
            //}
        }

        void transactionAmountInINR_TextChanged(object sender, EventArgs e)
        {
            TextBox amountTextBox = (TextBox)sender;
            if (amountTextBox.Tag == null)
            {
                return;
            }
            Guid panelGuid = (Guid)amountTextBox.Tag;
            if (mainPanelMap.ContainsKey(panelGuid))
            {
                PanelDetails panelDetails = mainPanelMap[panelGuid];
                foreach (PanelDetails childPanelDetails in panelDetails.ChildrenChequeDetails)
                {
                    try
                    {
                        TextBox chequeTextBox =
                            (TextBox)childPanelDetails.PanelWithControls.Controls[3];
                        chequeTextBox.Text = amountTextBox.Text;
                    }
                    catch { }
                }
            }
        }

        private void SetChequeRowDetailsPerParentHeadAndMode(PanelDetails parentRow)
        {
            // setting the bank name list for expense cheque transactions
            if (parentRow != null)
            {
                foreach (PanelDetails chequeDetailsPanelDetails in parentRow.ChildrenChequeDetails)
                {
                    ComboBox chequeDrawnOnBankComboBox = (ComboBox)chequeDetailsPanelDetails.PanelWithControls.Controls[4];
                    drawnOnBank_GotFocus(chequeDrawnOnBankComboBox, null);
                }
            }


            if (parentRow != null && parentRow.PanelWithControls.Controls.Count > 2)
            {
                StaticList staticListSelectedHead = null;
                StaticList staticListSelectedMode = null;

                ComboBox head = (ComboBox)parentRow.PanelWithControls.Controls[1];
                ComboBoxItem selectedItemHead = (ComboBoxItem)head.SelectedItem;
                if (selectedItemHead != null && selectedItemHead.Value != null)
                {
                    staticListSelectedHead = (StaticList)selectedItemHead.Value;
                }

                ComboBox transactionMode = (ComboBox)parentRow.PanelWithControls.Controls[2];
                ComboBoxItem selectedItemMode = (ComboBoxItem)transactionMode.SelectedItem;
                if (selectedItemMode != null && selectedItemMode.Value != null)
                {
                    staticListSelectedMode = (StaticList)selectedItemMode.Value;
                }

                string chequeStatusToSet = string.Empty;
                //string drawnOnBankToSet = string.Empty;

                if (staticListSelectedHead != null && staticListSelectedMode != null)
                {
                    if (staticListSelectedHead.ListItemCode.Equals("head_expense") &&
                        (staticListSelectedMode.ListItemCode.Equals("transaction_mode_cheque") || staticListSelectedMode.ListItemCode.Equals("transaction_mode_pettycashwithdrawal")))
                    {
                        chequeStatusToSet = "cheque_status_debited";
                        //drawnOnBankToSet = "bank_name_cosmos";
                    }

                    if (staticListSelectedHead.ListItemCode.Equals("head_income") &&
                        staticListSelectedMode.ListItemCode.Equals("transaction_mode_cheque"))
                    {
                        chequeStatusToSet = "cheque_status_credited";
                    }
                }


                if (parentRow.ChildrenChequeDetails.Count > 0)
                {
                    // get the last cheque row
                    PanelDetails chequeDetails = parentRow.ChildrenChequeDetails[parentRow.ChildrenChequeDetails.Count - 1];

                    if (chequeDetails.PanelWithControls.Controls.Count > 4)
                    {
                        int index = 0;
                        // set cheque status as debited
                        if (!string.IsNullOrEmpty(chequeStatusToSet))
                        {
                            ComboBox chequeStatus = (ComboBox)chequeDetails.PanelWithControls.Controls[2];
                            foreach (ComboBoxItem item in chequeStatus.Items)
                            {
                                StaticList staticList = (StaticList)item.Value;
                                if (staticList != null && staticList.ListItemCode.Equals(chequeStatusToSet))
                                {
                                    chequeStatus.SelectedIndex = index;
                                    break;
                                }

                                index++;
                            }
                        }

                        //// set bank name as cosmos for now
                        //index = 0;
                        //if (!string.IsNullOrEmpty(drawnOnBankToSet))
                        //{
                        //    ComboBox drawnOnBank = (ComboBox)chequeDetails.PanelWithControls.Controls[4];
                        //    foreach (ComboBoxItem item in drawnOnBank.Items)
                        //    {
                        //        StaticList staticList = (StaticList)item.Value;
                        //        if (staticList != null && staticList.ListItemCode.Equals(drawnOnBankToSet))
                        //        {
                        //            drawnOnBank.SelectedIndex = index;
                        //            break;
                        //        }

                        //        index++;
                        //    }
                        //}
                    }
                }
                //}
            }
        }

        #endregion Private Methods

        #region Public Methods
        #endregion Public Methods

    }
}